package com.oocl.crm.db;

import java.lang.reflect.Method;

import com.oocl.crm.base.DNode;
import com.oocl.crm.exception.ParameterErrorException;
import com.oocl.crm.pojo.User;
import com.oocl.crm.util.ReflectUtil;

/**
 * 存储用户数据的数据库 DB<br>
 * 具有增删改查基本功能<br>
 * 还有自增ID功能
 * 
 * @author GANAB
 * 
 */
public class CrmUserStore implements IUserSort {
	/**
	 * 该DB为单例模式
	 */
	private static CrmUserStore instance;

	/**
	 * 用户列表
	 */
	private UserLinkedList userlinkedList;

	/**
	 * 自增ID
	 */
	private Integer autoId;

	private CrmUserStore() {
		this.autoId = new Integer(0);
		this.userlinkedList = new UserLinkedList();
	}

	public static CrmUserStore getInstance() {
		if (instance == null) {
			instance = new CrmUserStore();
		}
		return instance;
	}

	/**
	 * 根据ID 查询用户
	 * 
	 * @param index
	 */
	public DNode<User> get(Integer id) throws ParameterErrorException {
		UserLinkedList dbList = CrmUserStore.getInstance().userlinkedList;
		if (id < 0) {
			throw new ParameterErrorException("User ID not less than 0");
		}
		DNode<User> other = dbList.getFirst();
		while (other != null) {
			if (other.data.getId() == id) {
				return other;
			} else {
				other = other.next;
			}
		}
		return null;
	}

	/**
	 * 根据多条件 查询用户 (参数为{name:3,sex:男}等等)
	 * 
	 * @param name
	 * @return
	 */
	public UserLinkedList get(String[] fields) throws ParameterErrorException {
		UserLinkedList tempUserList = null;
		if (fields.length <= 0) {
			throw new ParameterErrorException(
					"Loopup parameter cann't be null!");
		} else if (fields.length == 1 && fields[0]=="") {
			return this.userlinkedList;
		} else {
			// 创建二维数组，存储多条件的形参名和值
			String[][] keyValues = new String[fields.length][2];
			for (int i = 0; i < keyValues.length; i++) {
				keyValues[i][0] = fields[i].split(":")[0];
				keyValues[i][1] = fields[i].split(":")[1];
			}
			DNode<User> other = this.userlinkedList.getFirst();
			;
			tempUserList = new UserLinkedList();
			// 链表循环
			while (other != null) {
				boolean isFit = true;
				// 查询条件循环
				for (int i = 0; i < keyValues.length; i++) {
					Method m = null;
					Object fieldValue = null;
					try {
						m = other.data.getClass().getMethod(
								ReflectUtil
										.getGetterMethodName(keyValues[i][0]));
						fieldValue = m.invoke(other.data);

						if (fieldValue != null) {
							String temp = String.valueOf(fieldValue);
							// 如果参入条件与数据不相同，isFit设置为false，不加入到链表中
							if (!temp.equals(keyValues[i][1])) {
								isFit = false;
							}
						}
					} catch (Exception e) {
						throw new ParameterErrorException(
								"Loopup service reflect failure. Check parameter format!");
					}
				}
				// 如果所有条件都满足，则加入到链表中
				if (isFit) {
					tempUserList.addLastNode(other.data);
				}
				other = other.next;
			}

		}
		return tempUserList;
	}

	/**
	 * 增加用户
	 * 
	 * @param user
	 */
	public void add(User user) {
		userlinkedList.addLastNode(user);
	}

	/**
	 * 修改用户信息
	 * 
	 * @param user
	 * @throws ParameterErrorException
	 */
	public boolean update(User user, String fieldName, String value)
			throws ParameterErrorException {
		// 反射设值，避免多个IF判断
		Method m;
		try {
			m = user.getClass().getMethod(
					ReflectUtil.getSetterMethodName(fieldName), String.class);
			m.invoke(user, value);
			return true;
		} catch (Exception e) {
			throw new ParameterErrorException(
					"Update user exception: reflect failure!");
		}
	}

	/**
	 * 根据ID 移除用户
	 * 
	 * @param index
	 */
	public boolean remove(Integer id) throws ParameterErrorException {
		
		UserLinkedList dbList = CrmUserStore.getInstance().userlinkedList;
		if (id < 0) {
			throw new ParameterErrorException("User ID not less than 0");
		}
		DNode<User> targetNode = dbList.getFirst();
		while (targetNode != null) {
			if (targetNode.data.getId() == id) {
				if(targetNode.prev==null){
					this.userlinkedList.setFirst(targetNode.next);
				}else if(targetNode.next==null && targetNode.prev != null){
					targetNode.prev.next = targetNode.next;
					targetNode.prev = null;
				}
				if(targetNode.next == null){
					this.userlinkedList.setLast(targetNode.prev);
				}else{
					targetNode.next.prev = targetNode.prev;
					targetNode.next = null;
				}
				targetNode = null;
				userlinkedList.autoSubductionSize();
				return true;
			} else {
				targetNode = targetNode.next;
			}
		}
		return false;
	}

	/**
	 * 排序 by ID 
	 * 
	 * @throws ParameterErrorException
	 */
	public User[] sortById() {
		UserLinkedList list = CrmUserStore.getInstance().userlinkedList;
		DNode<User> listNode = list.getFirst();
		User[] userList = new User[list.getSize()];
		// 克隆链表
		int k = 0;
		while (listNode != null) {
			userList[k] = listNode.data;
			listNode = listNode.next;
			k++;
		}

		for (int i = 0; i < userList.length; i++) {
			for (int j = 1; j < userList.length - i; j++) {
				if (userList[j].getId() < userList[j - 1].getId()) {
					User temp = userList[j];
					userList[j] = userList[j - 1];
					userList[j - 1] = temp;
				}
			}
		}
		return userList;
	}

	/**
	 * 排序 by Name
	 */
	public User[] sortByName() {
		UserLinkedList list = CrmUserStore.getInstance().userlinkedList;
		DNode<User> listNode = list.getFirst();
		User[] userList = new User[list.getSize()];
		// 克隆链表
		int k = 0;
		while (listNode != null) {
			userList[k] = listNode.data;
			listNode = listNode.next;
			k++;
		}

		for (int i = 0; i < userList.length; i++) {
			for (int j = 1; j < userList.length - i; j++) {
				if ((userList[j].getName().compareTo(userList[j - 1].getName()))<0) {
					User temp = userList[j];
					userList[j] = userList[j - 1];
					userList[j - 1] = temp;
				}
			}
		}
		return userList;
	}

	/**
	 * 获得自增ID
	 * 
	 * @return
	 */
	public final Integer getAutoId() {
		return ++autoId;
	}
}
